home *** CD-ROM | disk | FTP | other *** search
- /* Compile with:
- * cc string.o array.o dict.o cgilib.o ht73.c -o ht73 -lsdbm
- */
-
- #include <sdbm.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include <string.h>
-
- #include "cgilib.h"
-
- #define DOMAINSIZE 30 /* Maximum size of domain name stored */
-
- /*
- * This structure is used to contain a movie's review information
- * withing the dbm database. The movie's name is not stored in
- * this structure because it is contained in the records key.
- */
- typedef struct
- {
- int lastVote; /* the last vote: 1 to 10 */
- int votes[10]; /* votes[i] is # of votes of i */
- char lastVoter[DOMAINSIZE];/* domain name of the last voter*/
- } REVIEW;
-
- /*
- * This structure is a node of a binary tree of movie names.
- */
- typedef struct _movienode
- {
- char *movie; /* The movie's title */
- struct _movienode *lt, *gt; /* Pointers to children */
- } MOVIENODE;
-
-
- DBM *db;
-
- /*
- * Insert a movie title into the binary tree
- */
- void insertMovie(char *movie, MOVIENODE **root)
- {
- /* Insert a new node if we are at the bottom of the tree */
- if (!*root)
- {
- *root = malloc(sizeof(MOVIENODE));
- (*root)->movie = movie;
- (*root)->lt = (*root)->gt = NULL;
- }
- /* Else traverse farther down the tree */
- else
- {
- insertMovie(movie, strcasecmp((*root)->movie,movie) < 0
- ? &(*root)->gt
- : &(*root)->lt);
- }
-
- }
-
-
- /*
- * Perform an in-order traversal of the binary tree of movies
- */
- void traverseMovies(MOVIENODE *root)
- {
- /* Don't do anything to an empty tree */
- if (!root) return;
-
- traverseMovies(root->lt);
- htmlMovie(root->movie);
- traverseMovies(root->gt);
-
- /* Free the dynamic memory associated with this node */
- free(root->movie);
- free(root);
- }
-
-
- htmlMovie(char *movie)
- {
- datum key, value;
- REVIEW *rev;
- int votes = 0;
- int sum = 0;
- int i;
-
- /* Convert the character string into a datum structure */
- key.dptr = movie;
- key.dsize = strlen(movie);
-
- value = sdbm_fetch(db,key);
- rev = (REVIEW *) value.dptr;
-
- for ( i = 0 ; i < 10 ; i++ )
- {
- sum += rev->votes[i]*(i+1);
- votes += rev->votes[i];
- }
-
- /*
- * Display information about this movie
- */
- printf("<H2>%s</H2><BLOCKQUOTE>", movie);
- printf("<B>Average: %2.2f", (float)sum/(float)votes);
- printf(" Votes: %d</B><BR>\n", votes);
- printf("<IMG SRC=\"ht72a.cgi?score=");
-
- for( i=0 ; i < 9 ; i++ )
- {
- printf("%d+",rev->votes[i]);
- }
-
- printf("%d",rev->votes[9]);
-
- printf("\" ALT=\"");
- for( i=0 ; i < 10 ; i++ )
- {
- printf("%d:%d ",i+1,rev->votes[i]);
- }
-
- printf("\"><BR>\n");
- printf("Last vote from <B>%s</B> who gave ", rev->lastVoter);
- printf("%s a %d out of 10.\n", movie, rev->lastVote);
-
- /*
- * Build the Form for voting for this movie
- */
- printf("<FORM ACTION=\"%s\">", getenv("SCRIPT_NAME"));
- printf("<INPUT TYPE=\"hidden\" NAME=\"movie\" value=\"%s\">",
- movie);
- printf("<SELECT NAME=\"score\">");
- for ( i = 1 ; i <= 10 ; i++ )
- {
- printf("<OPTION> %d",i);
- }
- printf("</SELECT><INPUT TYPE=\"submit\" value=\"Vote\">");
- printf("</FORM></BLOCKQUOTE><BR>\n");
- }
-
-
- void main()
- {
- Dictionary dataDict = readParse();
- datum key;
- MOVIENODE *root = NULL;
- char *tmp;
- int i;
- int score = dict_isKey(dataDict,"score")
- ? atoi(dict_valueForKey(dataDict,"score"))
- : 0;
- char *movie = dict_isKey(dataDict,"movie")
- ? dict_valueForKey(dataDict,"movie")
- : NULL;
-
- /* Output the HTML content type and header */
- printf("Content-type: text/html\n\n");
- printf("<HTML><HEAD><TITLE>Waite Movie Reviews</TITLE>");
- printf("</HEAD><BODY>");
- printf("<H1>Welcome to Waite Movie Reviews</H1><HR>");
-
- /*
- * If a vote is being registered
- */
- if ( movie && score >=1 && score <= 10 && strchr(movie,'<') == NULL)
- {
- datum value;
- REVIEW *rev_ptr;
- REVIEW rev;
-
- key.dptr = movie;
- key.dsize = strlen(movie);
-
- if (! (db = sdbm_open("movies", O_RDWR | O_CREAT, 0660)))
- exit(1);
-
- printf("Your vote of %d out of 10 for ", score);
- printf("<B>%s</B> has been recorded.<HR>\n",movie);
-
- value = sdbm_fetch(db,key);
-
- /* If this is the first vote for a new movie
- * Then we must initialize a new REVIEW structure
- * so that all of the votes have an initial value of 0
- */
- if ( ! value.dptr )
- {
- int i;
-
- for ( i=0 ; i<10 ; i++ )
- {
- rev.votes[i] = 0;
- }
- value.dptr = (char *) &rev;
- value.dsize = sizeof(REVIEW);
- }
-
- rev_ptr = (REVIEW *) value.dptr;
- strncpy(rev_ptr->lastVoter,
- getenv("REMOTE_HOST"),DOMAINSIZE);
- rev_ptr->lastVote = score;
- (rev_ptr->votes[score-1])++;
- sdbm_store(db,key,value,DBM_REPLACE);
- sdbm_close(db);
- }
-
- if (! (db = sdbm_open("movies", O_RDONLY | O_CREAT, 0660)))
- exit(1);
-
- for ( key = sdbm_firstkey(db) ;
- key.dptr != NULL ;
- key = sdbm_nextkey(db) )
- {
- /*
- * Allocate memory for the movie's title.
- * Allocate an extra byte to null terminate the string.
- */
- tmp = malloc(key.dsize+1);
-
- /* Copy the movie's title into tmp */
- bcopy(key.dptr,tmp,key.dsize);
- tmp[key.dsize] = '\0';
-
- /* Insert the movie's title into the binary tree */
- insertMovie(tmp,&root);
- }
-
- /*
- * Traverse the binary tree outputing each records
- * record and form in HTML format.
- */
- traverseMovies(root);
-
- /* Build the Form for voting for 'Other' */
- printf("<H2>Other</H2><BLOCKQUOTE>");
- printf("<FORM ACTION=\"%s\">", getenv("SCRIPT_NAME"));
- printf("<INPUT NAME=\"movie\">");
- printf("<SELECT NAME=\"score\">");
- for ( i = 1 ; i <= 10 ; i++ )
- {
- printf("<OPTION> %d",i);
- }
- printf("</SELECT><INPUT TYPE=\"submit\" value=\"Vote\">");
- printf("</FORM></BLOCKQUOTE><BR>\n");
- printf("<HR></BODY></HTML>");
-
- sdbm_close(db);
- }
-
-